<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2021/3/31
 * Time: 10:40
 */
declare(strict_types=1);

namespace App\Service;
use App\Model\Dao\MchAccountAccessDao;
use App\Model\Dao\MchAccountAccessDetailDao;
use App\Model\Dao\MchAccountDao;
use App\Model\Dao\MchInfoDao;
use App\Model\Dao\RateCommissionSalesDao;
use App\Model\Dao\RateCostDao;
use App\Model\Dao\RateSettleDao;
use App\Model\Dao\SysAdminDao;
use App\Model\Dao\TradeOrderDetailDao;
use App\Utils\CustomUtils;
use App\Utils\RedisUtils;
use Hyperf\DbConnection\Db;
use Hyperf\Di\Annotation\Inject;
use Exception;

/**
 * Class SettleSalesCommissionService
 * @package App\Service
 * 算佣金
 */
class SettleSalesCommissionService extends CommonService
{

    /**
     * @Inject()
     * @var TradeOrderDetailDao
     */
    private $TradeOrderDetailDao;

    /**
     * @Inject()
     * @var MchInfoDao
     */
    private $MchInfoDao;

    /**
     * @Inject()
     * @var SysAdminDao
     */
    private $SysAdminDao;

    /**
     * @Inject()
     * @var RateCommissionSalesDao
     */
    private $RateCommissionSalesDao;

    /**
     * @Inject()
     * @var RateCostDao
     */
    private $RateCostDao;

    /**
     * @Inject()
     * @var RateSettleDao
     */
    private $RateSettleDao;

    public function statAndPush($mchNo, $statStartTime, $statEndTime)
    {
        $mchNos = explode(',', $mchNo);
        $count = $this->TradeOrderDetailDao->getCountByMchNoAndTransStatusAndSettleTimeRange($mchNos, [6], $statStartTime, $statEndTime);

        $limit = 50;
        $pageSize = ceil($count / $limit);
        for ($i = 0; $i < $pageSize; $i ++) {
            $offset = $limit * $i;
            $list = $this->TradeOrderDetailDao->getByMchNoAndTransStatusAndSettleTimeRange($mchNos, [6], $statStartTime, $statEndTime, $limit, $offset);

            foreach ($list as $tradeOrder) {
                $rateSettle = $this->RateSettleDao->getByMchId($tradeOrder['mchId']);
                if(!$rateSettle) {
                    CustomUtils::xzxDebug('查询商户结算费率失败');
                }
                $this->handle($tradeOrder, $rateSettle);
            }
        }
    }

    /**
     * @param $tradeOrder
     * @param $rateSettle
     * 计算这个订单的佣金
     * 公式： （商户交易手续费率 - 通道交易手续费率） * 商户结算金额 * 佣金比例
     * 销售一级，销售二级
     */
    public function handle($tradeOrder, $rateSettle) {
        $mch = $this->MchInfoDao->get($tradeOrder['mchId']);
        // 没有关联销售
        if (empty($mch['salesId'])) {
            CustomUtils::xzxDebug("{$tradeOrder['mchNo']} 未关联销售");
            return;
        }

        // 查关联销售信息
        $sales = $this->SysAdminDao->get($mch['salesId']);
        if (empty($sales) || empty($sales['parentId'])) {
            CustomUtils::xzxDebug("{$tradeOrder['mchNo']} 关联销售找不到或未设置上级");
            return;
        }

        // 查销售佣金比例
        $rateCommission2 = $this->RateCommissionSalesDao->getWhere(['level' => 2]);
        $rateCommission1 = $this->RateCommissionSalesDao->getWhere(['level' => 1]);

        if (empty($rateCommission2) || empty($rateCommission1)) {
            CustomUtils::xzxDebug("未设置好一二级销售佣金比例");
            return;
        }

        // 查通道的成本
        $rateCost = $this->RateCostDao->getByChannelId($tradeOrder['channelId']);
        if (empty($rateCost)) {
            CustomUtils::xzxDebug("{$tradeOrder['channelName']} 未设置关联成本");
            return;
        }
        if ($rateCost['serviceFee'] >= $rateSettle['serviceFee']) {
            CustomUtils::xzxDebug("成本交易手续费率大于商户交易手续费率，无法计算佣金");
            return;
        }

        // 计算一级二级佣金
        bcscale(8);
        $settleAmount = strval($tradeOrder['settleAmount']);
        $differ = bcdiv(strval($rateSettle['serviceFee'] - $rateCost['serviceFee']), '10000');
        $rate2 = bcdiv(strval($rateCommission2['rate']), '10000');
        $salesCommission2 = round(bcmul(bcmul($differ, $settleAmount), $rate2));

        $rate1 = bcdiv(strval($rateCommission1['rate']), '10000');
        $salesCommission1 = round(bcmul(bcmul($differ, $settleAmount), $rate1));

        // 更新订单佣金信息
        $this->TradeOrderDetailDao->update($tradeOrder['id'], [
            'salesId1'          => $sales['parentId'],
            'salesId2'          => $sales['id'],
            'salesCommission1'  => $salesCommission1,
            'salesCommission2'  => $salesCommission2,
        ]);
    }

}